<?php
include_once $_SERVER['DOCUMENT_ROOT'].'/phorm/display/IDisplayObject.php';
class DisplayObject implements IDisplayObject
{
	public       $dictionary;
	protected    $source;
	protected    $url;
	protected    $dynamicProperties;
	
	/* Convenience Methods */
	public static function initWithURLAndDictionary($url, $dictionary)
	{
		$instance             = new DisplayObject();
		$instance->url        = $url;
		$instance->dictionary = $dictionary;
		
		return $instance;
	}
	public static function initWithURL($url)
	{
		$instance = new DisplayObject();
		$instance->url = $url;
		return $instance;
	}
	
	public static function initWithString($string)
	{
		$instance = new DisplayObject();
		$instance->source = $string;
		return $instance;
	}
	
	public static function initWithDictionary(array $dictionary)
	{
		$instance = new DisplayObject();
		$instance->setDataProvider($dictionary);
		
		return $instance;
	}
	
	public function render()
	{
		if($this->source)
		{
			$output = $this->source;
			foreach($this->dictionary as $key => $value)
				$this->applyPropertyToView($key, $value, $output);
			
			return $output;
		}
		else
		{
			if(!in_array("displayObjectRenderer", stream_get_filters()))
				stream_filter_register("displayObjectRenderer", "DisplayObjectRenderer");
				
			$pointer = fopen($this->url, "r");
			
			if($this->dictionary)
				stream_filter_append($pointer, "displayObjectRenderer", STREAM_FILTER_READ, $this->dictionary);
			else
				stream_filter_append($pointer, "displayObjectRenderer", STREAM_FILTER_READ);
			
			return stream_get_contents($pointer);
		}
	}
	
	protected function applyPropertyToView($name, $value, &$component)
	{
		$component = str_replace("{".$name."}", $value, $component);
	}
	
	public function setDataProvider($dictionary)
	{
		foreach($dictionary as $key=>$value)
			$this->$key = $value;
	}
	
	public function __toString()
	{
		return $this->render();
	}
}

class DisplayObjectRenderer extends php_user_filter 
{
	public function filter($in, $out, &$consumed, $closing)
	{
		while ($bucket = stream_bucket_make_writeable($in)) 
		{

			if(count($this->params))
			{
				foreach($this->params as $key => $value)
				{
					if(strpos($bucket->data, '{'.$key.'}') !== false)
						$bucket->data = str_replace('{'.$key.'}', $value, $bucket->data);
				}
			}
			
			$this->cleanup($bucket->data);
			
			$consumed += $bucket->datalen;
			stream_bucket_append($out, $bucket);
		}
		return PSFS_PASS_ON;
	}
	
	private function cleanup(&$data)
	{
		$data = preg_replace('/\{[\d\w]+\}/', '', $data);
	}
	
	public function onCreate()
	{
		return true;
	}
}

?>